package br.com.wepa.webapps.orca.logica.negocio.facade;

import javax.persistence.PersistenceException;

import br.com.wepa.webapps.logger.TraceLogger;
import br.com.wepa.webapps.orca.controle.actions.usuario.LoginIndisponivelException;
import br.com.wepa.webapps.orca.logica.modelo.Construtora;
import br.com.wepa.webapps.orca.logica.modelo.Credencial;
import br.com.wepa.webapps.orca.logica.modelo.Usuario;
import br.com.wepa.webapps.orca.logica.negocio.BusinessConstants;
import br.com.wepa.webapps.orca.logica.negocio.BusinessException;
import br.com.wepa.webapps.orca.logica.negocio.BusinessManager;
import br.com.wepa.webapps.orca.logica.negocio.facade.basic.GenericTO;
import br.com.wepa.webapps.orca.logica.negocio.facade.to.UsuarioTO;
import br.com.wepa.webapps.orca.logica.persistencia.UsuarioDAO;
import br.com.wepa.webapps.orca.logica.persistencia.search.BeanSearch;
import br.com.wepa.webapps.orca.logica.persistencia.transaction.Transaction;
import br.com.wepa.webapps.orca.util.bean.BeanHelperUtil;

class UsuarioFacade extends
		BusinessManager<UsuarioTO, Usuario, Integer, UsuarioDAO> implements
		UsuarioFacadeHome {
	
	private static TraceLogger logger  = new TraceLogger(UsuarioFacade.class);

	public UsuarioFacade() {
		super();
	}
	
	
	private void testLoginDisponivel(UsuarioTO to) throws BusinessException {
		logger.entering();
		try {
			boolean disponivel = true;
			Usuario usuario = dao.newInstance();
			usuario.setLogin(to.getLogin());

			usuario = dao.findUnique(usuario);

			if (usuario != null && usuario.getIdUsuario() != to.getIdUsuario()) {
				disponivel = false;
			}

			if (!disponivel)
				throw new LoginIndisponivelException();
		} catch (PersistenceException e) {
			throw new BusinessException(e.getMessage(), e);
		}

		logger.exiting();
	}
	
	
	@Override
	@Transaction
	public UsuarioTO persist(UsuarioTO to) throws BusinessException {
		logger.entering();
		try {
			
			Usuario model = dao.newInstance();
			BeanHelperUtil.copyProperties(model, to);

			if (to.getUpdate()) {
				GenericTO storeTO = to.getStoreTO();
				if (storeTO == null
						|| !storeTO.getClass().equals(to.getClass())) {
					throw new Exception(
							BusinessConstants.ERROR_UPDATE_TRANSFER_OBJECT_TYPE);
				}
				BeanHelperUtil.copyProperties(model, to.getStoreTO());
				testLoginDisponivel((UsuarioTO)to.getStoreTO());
				model = dao.makePersistent(model);
			} else {
				if (to.getId() == null || !dao.exists(to.getId())) {
					testLoginDisponivel((UsuarioTO)to);
					to.setId(dao.create(model));
				} else {
					throw new BusinessException(
							BusinessConstants.ERROR_REGISTRO_DUPLICADO);
				}
			}

		} catch (PersistenceException e) {
			throw new BusinessException(e.getMessage(), e);
		} catch (BusinessException e) {
			throw e;
		} catch (Exception e) {
			throw new BusinessException(e.getMessage(), e);
		}

		logger.exiting();
		return to;
	}
	
	
	@Override
	public UsuarioTO find(UsuarioTO to) throws BusinessException {
		to.addOrder("nome", true);
		to.addOrder("login", true);
		return super.find(to);
	}
	
	@Override
	public UsuarioTO findAll(UsuarioTO to) throws BusinessException {
		to.addOrder("nome", true);
		to.addOrder("login", true);
		return super.findAll(to);
	}
	
	@SuppressWarnings("unchecked")
	@Override	
	public UsuarioTO setUp(UsuarioTO to) throws BusinessException {
		logger.entering();		
		to.getSearcher().addSearchBean("credencialList", new Credencial());	
		BeanSearch bean =  new BeanSearch(new Construtora());
		bean.addOrder("nome",true);
		to.getSearcher().addSearch("construtoraList", bean);
		
		to.enableSearcher();		
		to = super.setUp(to);
		
		logger.exiting();
		return to;
	}
}
